﻿/*
Desc:MediatR事件总线
Author:Joker
CreatedDate:24-02-02
*/

using ElectronicMall.Domain.Abstractions.Events;
using MediatR;

namespace ElectronicMall.Domain.Buses.MediatR.Events
{
    /// <summary>
    /// MediatR事件总线
    /// </summary>
    public class MediatREventBus : IEventBus
    {

        protected readonly IMediator mediator;
        protected readonly IEventStore eventStore;

        public MediatREventBus(IMediator mediator, IEventStore eventStore)
        {
            this.mediator = mediator;
            this.eventStore = eventStore;
        }

        public void PublishEvent(IEvent @event)
        {
            PublishEventAsync(@event).Wait();
        }

        public Task PublishEventAsync(IEvent @event, CancellationToken cancellationToken = default)
        {
            return Task.WhenAll(eventStore?.SaveAsync(@event, cancellationToken) ?? Task.CompletedTask, mediator.Publish(@event, cancellationToken));
        }

    }


    /// <summary>
    /// 有返回值的MediatR事件总线
    /// </summary>
    /// <typeparam name="TResult">返回值类型</typeparam>
    public class MediatREventBus<TResult> : MediatREventBus, IEventBus<TResult>
    {
        public MediatREventBus(IMediator mediator, IEventStore eventStore)
            : base(mediator, eventStore)
        {
        }

        TResult? IEventBus<TResult>.PublishEvent(IEvent @event)
        {
            PublishEventAsync(@event).Wait();
            return default;
        }

        Task<TResult?> IEventBus<TResult>.PublishEventAsync(IEvent @event, CancellationToken cancellationToken)
        {
            eventStore?.SaveAsync(@event, cancellationToken);
            mediator.Publish(@event, cancellationToken);
            return Task.FromResult(default(TResult));
        }
    }
}
